//: [Previous](@previous)

import Foundation

var str = "Hello, playground"
//: 4.创建一个SequenceType,用于生成斐波那契数列。创建一个SequenceType,用于生成一个GUID字符串构成的序列（该序列可用于创建记录ID)

//结构体，复制了一份
struct ListGenerator<T>: GeneratorType {
    var items: ListNumber<T>
    var iteration: Int = 0
    var done: Bool = false
    
    init(items: ListNumber<T>) {
        self.items = ListNumber.init(items: items.items, initialPosition: items.currentPosition)
    }
    
    mutating func next() -> T? {
        if done {
            preconditionFailure("ListGenerator already completed")
        }
        if iteration >= items.count {
            done = true
            return nil
        }
        iteration += 1
        return items.next()
    }
}

class ListNumber<T>: SequenceType {
    var items = [T]()
    var currentPosition = 0
    
    var count: Int {
        return items.count
    }
    
    var isEmpty: Bool {
        return items.isEmpty
    }
    
    func append(item: T) {
        items.append(item)
    }
    
    convenience init(items: [T], initialPosition: Int = 0) {
        self.init()
        self.items = items
        currentPosition = initialPosition
    }
    
    func next() -> T? {
        if self.isEmpty {
            return nil
        }
        if currentPosition == self.count - 1 {
            return nil
        }
        let item = self[currentPosition]
        currentPosition = (currentPosition + 1) % self.count
        return item
    }
    
    subscript (i: Int) -> T? {
        if self.isEmpty {
            return nil
        }
        return items[i % self.count]
    }
    
    func generate() -> ListGenerator<T> {
        return ListGenerator.init(items: self)
    }
}

//斐波那契数列
class fabListNumber<T: IntegerType>: ListNumber<T> {
    func nexFabData() -> T {
        currentPosition += 1
        if currentPosition < self.count {
            return self[currentPosition]!
        }
        let item = self[currentPosition - 1]! + self[currentPosition - 2]!
        self.append(item)
        return item
    }
}

let fab = fabListNumber<Int>(items: [1, 4])
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()
fab.nexFabData()

//生成GUID序列，每次生成的GUID都是不一样的
class GUIDListNumber: ListNumber<String> {
    func nextGUID() -> String {
        let uuid = NSUUID.init().UUIDString
        self.append(uuid)
        currentPosition += 1
        return uuid
    }
}

let uuid = GUIDListNumber.init()
uuid.nextGUID()
uuid.nextGUID()
uuid.nextGUID()
uuid.nextGUID()
uuid.nextGUID()
uuid.nextGUID()
uuid.nextGUID()
uuid.nextGUID()

//: 5.创建一个自定义的前缀运算符，采用一个数组作为操作数（用于包含一系列Comparable对象）。该运算符可创建一个逆序的数组。你会使用什么字符来作为整个运算符的名字？它比起相同作用的命名函数来说，是否有更多的优点？
prefix operator ... {}
prefix func ...<T: Comparable>(items: [T]) -> [T]{
    let lastItems = items.sort { (a, b) -> Bool in
        return a <= b
    }
    return lastItems
}

prefix operator >>> {}
prefix func >>><T: Comparable>(items: [T]) -> [T] {
    let lastItems = items.sort { (a, b) -> Bool in
        return a > b
    }
    return lastItems
}

let sb: [Int] = [1, 5, 0, 3, 4, 2]
...sb
>>>sb

//: [Next](@next)
